#include "py32f0xx_hal.h"
#include "adc.h"


ADC_HandleTypeDef hadc1;
struct ADCInitParam g_ADCInitParam;
uint8_t g_IsADC1Init = 0;

/**
  * @brief  adc温度传感器初始化
  * @param param
  * @note  	无
  * @retval 无
  */
int32_t ADC1_Init(const struct ADCInitParam *param) {

    if ( g_IsADC1Init == 1 ) {
        printf("%s: ADC1 is already initialized", __func__);
        return -1;
    }

    if ( param == NULL ) {
        printf("%s: param is nullptr", __func__);
        return -2;
    }
    g_ADCInitParam = *param;
    GPIO_InitTypeDef GPIO_InitStruct = {};



    if (g_ADCInitParam.gpioPort == GPIOA) {
        __HAL_RCC_GPIOA_CLK_ENABLE();
    } else if (g_ADCInitParam.gpioPort == GPIOB) {
        __HAL_RCC_GPIOB_CLK_ENABLE();
    } else if (g_ADCInitParam.gpioPort == GPIOC) {
        __HAL_RCC_GPIOC_CLK_ENABLE();
    } else {
        printf("%s: UnSupport GPIO Port: %p \r\n", __func__,  g_ADCInitParam.gpioPort);
        return -3;
    }

    GPIO_InitStruct.Pin = g_ADCInitParam.gpioPin;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(g_ADCInitParam.gpioPort, &GPIO_InitStruct);

    __HAL_RCC_ADC_CLK_ENABLE(); /* 使能 ADC 时钟 */
    hadc1.Instance = ADC1;
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV32; /* 设置adc时钟*/
    hadc1.Init.Resolution = ADC_RESOLUTION_12B; /* 12位 转换模式 */
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* 数据右对齐 */
    hadc1.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; /* 顺序扫描*/
    hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* 单次转换 */
    hadc1.Init.LowPowerAutoWait = DISABLE; /* 自动延迟转换功能禁用 */
    hadc1.Init.ContinuousConvMode = DISABLE; /* 禁用连续模式 */
    hadc1.Init.DiscontinuousConvMode = DISABLE; /* 禁用不连续模式 */
    hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* 软件触发 */
    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* 软件触发时，该参数无效 */
    hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* 在溢出的情况下，DR寄存器被最后一次转换结果覆盖 */
    hadc1.Init.SamplingTimeCommon = ADC_SAMPLETIME_41CYCLES_5; /* 通道采样时间为41.5 ADC时钟周期 */
    HAL_ADC_Init(&hadc1);

    HAL_ADCEx_Calibration_Start(&hadc1);
    g_IsADC1Init = 1;
    return 0;
}

uint16_t ADC1_getValueByChannel(uint32_t channel ) {

    if ( g_IsADC1Init == 0 ) {
        printf("%s: ADC1 is not initialized", __func__);
        return 0xffff;
    }

    //设置通道
    ADC_ChannelConfTypeDef sConfig = {};
    sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
    sConfig.Channel = channel;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);

    //开始转换
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 1000000);
    return HAL_ADC_GetValue(&hadc1);
}

void ADC1_Deinit(void) {
    if ( g_IsADC1Init == 0 ) {
        printf("%s: ADC1 is not initialized", __func__);
        return;
    }
    HAL_ADC_DeInit(&hadc1);
    __HAL_RCC_ADC_CLK_DISABLE();

    if (g_ADCInitParam.gpioPort == GPIOA) {
        __HAL_RCC_GPIOA_CLK_DISABLE();
    } else if (g_ADCInitParam.gpioPort == GPIOB) {
        __HAL_RCC_GPIOB_CLK_DISABLE();
    } else if (g_ADCInitParam.gpioPort == GPIOC) {
        __HAL_RCC_GPIOC_CLK_DISABLE();
    }

    HAL_GPIO_DeInit(g_ADCInitParam.gpioPort, g_ADCInitParam.gpioPin);

    g_IsADC1Init = 0;
}

void ADC_COMP_IRQHandler(void)
{
    HAL_ADC_IRQHandler(&hadc1);
}
